iT邦幫忙

2024 iThome 鐵人賽

DAY 26
0
Modern Web

Super Easy CSS,極度簡單 PART 2!寫出漂亮的 CSS系列 第 26

#60 利用 checkbox,做到純 CSS 開關網頁選單、收合側邊欄

  • 分享至 

  • xImage
  •  

上篇我們教了大家如何客製化 checkboxradio 樣式,其實運用同樣的原理,我們也可以做到簡單的互相切換(toggle)行為,例如:「點了就開,再點就關」這種動作。

所以,今天我們來做簡單的網頁選單吧!


基本概念

幫大家複習一下要用的小技巧:

  1. HTML 中 <label> 中的 for 屬性可以選取到 radio / checkbox 的 id 的特性,例如:

    <div class="check-group">
        <input type="checkbox" id="check-1">
        <label for="check-1">Text</label> <!-- 點選文字可勾起 checkbox -->
    </div>
    
  2. CSS 中的選取兄弟的選擇器(~+),幫大家複習一下選擇器:

    1. 使用加號 + 是選取到後面的第一個

    2. 使用波浪號 ~ 是選取到後面全部兄弟

      延伸閱讀:#08 CSS 選擇器總整理!id、class、:nth-child(n)、:not、:where、:is、:has 都難不倒我

  3. CSS 中的偽類 ::checked


DEMO 1:滿版網頁選單

用這些原理,我們可以來做一個簡單的選單:

DEMO: Pure CSS toggle menu

HTML

<input type="checkbox" id="menu-toggle">
<label for="menu-toggle" class="btn-toggle"></label>
<nav class="nav-main">
    <ul>
        <li>
            <a href="#">About Me</a>
        </li>
        <li>
            <a href="#">Works</a>
        </li>
        <li>
            <a href="#">Contact</a>
        </li>
    </ul>
</nav>

CSS

隱藏起 checkbox (#menu-toggle) ,然後當他為 checked 狀態時,改變漢堡按鈕的線條角度,並且把我們原本隱藏按不到的選單(.nav-main)改為出現:

#menu-toggle{
    display: none;
}
#menu-toggle:checked{
    + .btn-toggle:before{
        transform: rotate(-27deg);
    }
    + .btn-toggle:after{
        transform: rotate(27deg);
    }
    ~ .nav-main{
        opacity: 1;
        pointer-events: auto;
    }
}

DEMO 2:縮合側邊欄

用一樣的原理,我們也可以來做一個可以往旁邊縮起側邊欄的版面,這常見在後台系統中:

DEMO: Pure CSS toggle aside

HTML

<div class="content">
    <input type="checkbox" id="toggle-aside">
    <main id="col-main">
        <nav class="navbar">
            <label for="toggle-aside">
                <span class="material-icons">menu_open</span>
            </label>
            <h1>Title</h1>
        </nav>
    </main>
    <aside id="col-aside"></aside>
</div>

CSS

這邊的原理是:當 checkboxchecked 狀態時,側邊欄會往左偏移自己的寬度大小,於是會往左滑消失於畫面之中。

:root{
    --aside-width: 200px;
}

#toggle-aside{
    display: none;
}
#toggle-aside:checked{
    ~ #col-aside{
        margin-left: calc(var(--aside-width) * -1);
    }
    ~ #col-main{
        label[for="toggle-aside"] .material-icons{
            transform: rotate(180deg);
        }
    }
}

(而最外層的 .content 我有下 overflow: hidden; 以防萬一出現奇怪的橫向捲軸,雖然往視窗外左偏通常不會產生捲軸。如果有東西往視窗外右偏通常都會出現捲軸,大家要注意一下。)

CSS will-change 優化

這種版面常見在後台系統中,所以有可能我兩邊的內容都非常、非常多,比如很長的清單資料等等,有可能在改變寬度時,造成卡頓。

我們在 #54 篇時有建議:「除了透明度(opacity)和 transform,不要改變任何屬性」,但是我在這裡不得不改變寬度時怎麼辦?這時候就可以使用 will-change 了。

延伸閱讀:#54 網頁渲染動畫的建議 & will-change 的使用時機

will-change 屬性是告訴瀏覽器即將會改變的 CSS 屬性,讓瀏覽器預先做出最佳化處理。然而,過度使用 will-change 可能會耗費大量資源,因此需要謹慎使用。建議在需要動畫效果的父層元素 hover 時才啟動 will-change,確保在最需要的時候啟用最佳化。

所以我們用 CSS 告訴瀏覽器:
#col-main 裡面有 label[for="toggle-aside"] 被 hover 時,#col-main 可能會改變寬度,而他後面的 #col-aside 可能會改變 margin-left 。這樣,瀏覽器就會做出最佳處理,畫面就可能比較不卡囉!

#col-main:has(label[for="toggle-aside"]:hover){
    will-change: width;
    ~ #col-aside{
        will-change: margin-left;
    }
}

以上兩個 DEMO 都是用 checkbox 做到簡單的互相切換(toggle)行為,畫面細節的 Code 請去看 DEMO 連結會更詳細。這些 DEMO 是為了解釋基本原理,實際在開發中,排版的細節可能更多,也可能會搭配自己定義的變數或 UI 框架,到時候需要依據自己的需求調整喔!


上一篇
#59 客製化 radio、checkbox 樣式,製作開關按鈕 (Switch Button)
下一篇
#61 利用 checkbox/ radio 與 CSS grid,做到純 CSS FAQ 開合選單(Collapse 折疊 / Accordion 手風琴效果)
系列文
Super Easy CSS,極度簡單 PART 2!寫出漂亮的 CSS30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言